iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
自我挑戰組

硬體學習日記系列 第 27

Day-27 arduino介紹-9 7-segment

  • 分享至 

  • xImage
  •  

之前有介紹過7-segment的運作原理,今天要在arduino使用7-segment這個元件~

在模擬器中,arduino有提供1-digit的7-segment以及4-digit的7-segment。
https://ithelp.ithome.com.tw/upload/images/20240904/20168362WLAANSNLIs.png
他們共同的引腳有A、B、C、D、E、F、G、DP;這幾個引腳是負責決定「段」的顯示,而DP是用來控制小數點的部分。
那在4-digit的部分,因為還要控制要由哪一個7-segment來顯示數字,所以他比1-digit的多了四個引腳-DIG1、DIG2、DIG3、DIG4,要控制由誰發亮,就寫入指定的引腳,狀態設為HIGH,等等舉例會使用到。

先來介紹1-digit的元件~

1-digit

那從模擬器的圖能看到,上下邊皆有五個引腳,這些引腳代表了A~DP,還有兩個是COM1及COM2。
A~DP的部分,接上數位腳位,這邊就先接在D2~D9。
COM1及COM2是公共引腳,這邊可以不用接。

接好後的樣子:
https://ithelp.ithome.com.tw/upload/images/20240904/20168362sA6PUlDS5L.png

再來看程式碼。

因為要連接的引腳有「7段+DP」,所以我開一個segment陣列,負責存這7個段接到的腳位,以及DP連接的腳位,這邊就根據接線的狀況寫啦~
那接著是數字0~9的部分,再開一個number[10][8]的二維陣列,10代表有10個數字(0~9)、8代表「7段+DP」,其中儲存的值只有0跟1,row的索引值即為代表的數字,根據數字來決定他的「七段+DP」的狀態,1為亮、0為不亮。
那因為這邊其實不會用到DP,所以可以省略DP的部分,就陣列都少開一個空間。
那變數的部分就宣告完成!接著是setup,這邊的話八個使用到的腳位要設為OUTPUT。
然後是loop,一開始我先寫一個function,用來初始化LED燈,讓他都不亮。
然後要把7-segment打開。
接著是主要的displayNumber啦~這邊設定是從0亮到9、再從0開始繼續亮。
displayNumber在一個for迴圈內,這個for迴圈會由0跑到9,所以displayNumber要顯示的數字就是根據for迴圈當前的索引值。

首先我先測當前數字的8個值,如果是1就亮該LED段、0就跳過,且亮1秒。
這邊要注意的是,在這個7-segment的LED片段中,LOW表示亮、HIGH表示關,然後把要亮的片段都打開後,再執行delay。
亮好1秒後,我再呼叫一次initial,把所有LED片段關掉,維持關掉的狀態0.5秒。
然後再繼續亮下一個數字。

int segment[8] = {2,3,4,5,6,7,8,9};
int number[10][8] = 
{
  {1,1,1,1,1,1,0,0}, //0
  {0,1,1,0,0,0,0,0}, //1
  {1,1,0,1,1,0,1,0}, //2
  {1,1,1,1,0,0,1,0}, //3
  {0,1,1,0,0,1,1,0}, //4
  {1,0,1,1,0,1,1,0}, //5
  {1,0,1,1,1,1,1,0}, //6
  {1,1,1,0,0,0,0,0}, //7
  {1,1,1,1,1,1,1,0}, //8
  {1,1,1,1,0,1,1,0} //9
};

void setup() { //將8個腳位設為OUTPUT
  for( int i = 0; i < 8; ++i ){
    pinMode( segment[i], OUTPUT );
  }
}

void loop()
{
  initial(); //初始化
  digitalWrite(10,HIGH); //打開7-segment
  for( int i = 0; i < 10; ++i ){ //從0跑到9
    displayNumber( i ); //在7-segment顯示當前for迴圈的索引值
    delay(1000); //顯示1秒
    initial(); //關掉
    delay(500); //延遲0.5秒
  }
}

void initial()
{
  for( int i = 0; i < 8; ++i ){
    digitalWrite( segment[i],HIGH ); //把每個片段都關掉
  }
}

void displayNumber( int i )
{
  for( int j = 0; j < 8; ++j ){
    if( number[i][j] == 1 ){ //表示要亮
      digitalWrite( segment[j], LOW ); //打開該LED片段
    }
  }
}

大概就是這樣~

接著來看4-digit的部分。

4-digit

A~DP引腳的部分,跟1-digit一樣,連接到arduino板上的腳位(使用D2~D9)。
再來是1-digit沒有的的DIG1~DIG4的部分,這邊就使用D10~D13。
喔對,然後4-digit沒有COM1跟COM2。

放上接好的圖~
https://ithelp.ithome.com.tw/upload/images/20240904/20168362MabmTRdUWp.png

接好後,就根據接線的狀態來寫code啦~
這邊因為多了DIG1~DIG4,所以多設了一個陣列display[4],用來儲存這四個DIG分別接在哪一個角位。
然後因為我想要四個7-segment輪流顯示數值、一次只有一個顯示,所以我新增了一個變數k,用來表示現在要在哪一個7-segment顯示數值;k初值為0,每亮一次就+1,然後再mod 4取餘數,這是其中一個輪流0~3的方法。
其餘部分就跟1-digit的差不多~

以下的程式碼,執行後會是從0開始顯示到9,再回到0,然後四個7-segment會輪流顯示。

int display[4] = {10,11,12,13};
int segment[8] = {2,3,4,5,6,7,8,9};
int number[10][8] = 
{
  {1,1,1,1,1,1,0,0}, //0
  {0,1,1,0,0,0,0,0}, //1
  {1,1,0,1,1,0,1,0}, //2
  {1,1,1,1,0,0,1,0}, //3
  {0,1,1,0,0,1,1,0}, //4
  {1,0,1,1,0,1,1,0}, //5
  {1,0,1,1,1,1,1,0}, //6
  {1,1,1,0,0,0,0,0}, //7
  {1,1,1,1,1,1,1,0}, //8
  {1,1,1,1,0,1,1,0} //9
};

int k = 0;

void setup() {
  for( int i = 0; i < 8; ++i ){
    pinMode( segment[i], OUTPUT );
  }
}

void loop()
{
  initial();
  for( int i = 0; i < 10; ++i ){
    digitalWrite( display[k%4], HIGH );
    displayNumber( i );
    delay(1000);
    initial();
    delay(500);
    k++;
  }
}

void initial()
{
  digitalWrite( display[k%4], LOW ); //把當前使用的7-segment關掉
  for( int i = 0; i < 8; ++i ){
    digitalWrite( segment[i],HIGH );
  }
}

void displayNumber( int i )
{
  for( int j = 0; j < 8; ++j ){
    if( number[i][j] == 1 ){
      digitalWrite( segment[j], LOW );
    }
  }
}

那今天就先這樣~


上一篇
Day-26 arduino介紹-8 keypad
下一篇
Day-28 arduino介紹-10 OLED
系列文
硬體學習日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言